/**
 * 
 */
package edu.umd.clip.lm.model.training;

import java.io.*;
import java.util.zip.*;

/**
 * @author Denis Filimonov <den@cs.umd.edu>
 *
 */
public abstract class ActiveNodeStorage<T> {
	
	public class ActiveNodeCollection {
		final String name;
		
		protected ActiveNodeCollection(String name) {
			this.name = name;
		}
		
		public T getNode(int id) {
			return getActiveNode(this, id);
		}
		
		public boolean putNode(int id, T node) {
			return putActiveNode(this, id, node);
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + ((name == null) ? 0 : name.hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			//if (!(obj instanceof ActiveNodeCollection))
			//	return false;
			ActiveNodeCollection other = (ActiveNodeCollection) obj;
			if (name == null) {
				if (other.name != null)
					return false;
			} else if (!name.equals(other.name))
				return false;
			return true;
		}

		@Override
		public String toString() {
			return "ActiveNodeCollection [name=" + name + "]";
		}

		protected String getName() {
			return name;
		}
	}
	
	public abstract boolean open();
	public abstract boolean close();
	
	public abstract ActiveNodeCollection createCollection(String name);
	
	public abstract ActiveNodeCollection getCollection(String name);
	
	public abstract boolean removeCollection(String name);
	
	protected abstract T getActiveNode(ActiveNodeCollection collection, int id);
	
	protected abstract boolean putActiveNode(ActiveNodeCollection collection, int id, T node);
	
	protected static <T> byte[] serializeActiveNode(T node) {
		ByteArrayOutputStream backend = new ByteArrayOutputStream(8192);
		try {
			ObjectOutputStream out = new ObjectOutputStream(new GZIPOutputStream(backend));
			out.writeObject(node);
			out.close();
		} catch(IOException e) {
			e.printStackTrace();
		}
		return backend.toByteArray();
	}
	
	protected static <T> T deserializeActiveNode(byte[] buffer) {
		ByteArrayInputStream backend = new ByteArrayInputStream(buffer);
		try {
			ObjectInputStream in = new ObjectInputStream(new GZIPInputStream(backend));
			T node = (T) in.readObject();
			in.close();
			return node;
		} catch(IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
}
